import { Request, Response } from 'express';
import { userService } from './service';
import { AuthRequest } from '../../types/auth';
import jwt from 'jsonwebtoken';
import config from '../../config';
import { AppDataSource } from '../../config/database';
import { User, SystemUserStatus, SubscriptionStatus } from '../../entities/User';
import { SystemMessage, MessageType, MessageStatus } from '../../entities/SystemMessage';
import axios from 'axios';
import moment from 'moment';
import { createWxSDK } from '../../sdk/weixin';


/**
 * 获取用户最新信息
 */
export const getUserLatestInfo = async (req: AuthRequest, res: Response) => {
  try {
    const currentUser = req.user;

    if (!currentUser || !currentUser.id) {
      return res.status(401).json({
        success: false,
        message: '用户未登录'
      });
    }

    const user = await userService.findById(currentUser.id);
    
    if (!user) {
      return res.status(404).json({
        success: false,
        message: '用户不存在'
      });
    }

    res.json({
      success: true,
      data: user,
      message: '获取用户信息成功'
    });
  } catch (error: any) {
    res.status(500).json({
      success: false,
      message: error.message || '获取用户信息失败'
    });
  }
};

/**
 * 退出登录
 */
export const logout = async (req: AuthRequest, res: Response) => {
  try {
    const currentUser = req.user;

    if (!currentUser || !currentUser.id) {
      return res.status(401).json({
        success: false,
        message: '用户未登录'
      });
    }

    // 创建一个立即过期的 token 来替换当前的 token
    const expiredToken = jwt.sign(
      {
        id: currentUser.id,
        name: currentUser.name,
        mobile: currentUser.mobile
      },
      config.auth.JWT_SECRET,
      { expiresIn: '1s' } // 设置为1秒后过期
    );

    res.json({
      success: true,
      message: '退出登录成功',
      data: {
        token: expiredToken
      }
    });
  } catch (error: any) {
    res.status(500).json({
      success: false,
      message: error.message || '退出登录失败'
    });
  }
};

/**
 * 更新用户信息
 * 允许更新：用户姓名，性别，身份证号，户籍地址，居住地址，手机号，身份证照片，考号，
 * 省份，考试类型，成绩，准考证图片，第一志愿，第二志愿，家长姓名，联系电话，备注，
 * 消息订阅状态
 */
export const updateUserInfo = async (req: AuthRequest, res: Response) => {
  try {
    const currentUser = req.user;

    if (!currentUser || !currentUser.id) {
      return res.status(401).json({
        success: false,
        message: '用户未登录'
      });
    }

    // 获取要更新的字段
    const {
      name,
      gender,
      idCard,
      permanentAddress,
      address,
      mobile,
      idCardFrontPhoto,
      examNumber,
      province,
      examType,
      score,
      admissionTicketPhoto,
      firstChoice,
      secondChoice,
      parentName,
      parentMobile,
      remarks,
      subscriptionStatus
    } = req.body;

    // 构建更新数据对象，只包含提供的字段
    const updateData: any = {};
    
    if (name !== undefined) updateData.name = name;
    if (gender !== undefined) updateData.gender = gender;
    if (idCard !== undefined) updateData.idCard = idCard;
    if (permanentAddress !== undefined) updateData.permanentAddress = permanentAddress;
    if (address !== undefined) updateData.address = address;
    if (mobile !== undefined) updateData.mobile = mobile;
    if (idCardFrontPhoto !== undefined) updateData.idCardFrontPhoto = idCardFrontPhoto;
    if (examNumber !== undefined) updateData.examNumber = examNumber;
    if (province !== undefined) updateData.province = province;
    if (examType !== undefined) updateData.examType = examType;
    if (score !== undefined) updateData.score = score;
    if (admissionTicketPhoto !== undefined) updateData.admissionTicketPhoto = admissionTicketPhoto;
    if (firstChoice !== undefined) updateData.firstChoice = firstChoice;
    if (secondChoice !== undefined) updateData.secondChoice = secondChoice;
    if (parentName !== undefined) updateData.parentName = parentName;
    if (parentMobile !== undefined) updateData.parentMobile = parentMobile;
    if (remarks !== undefined) updateData.remarks = remarks;
    if (subscriptionStatus !== undefined) updateData.subscriptionStatus = subscriptionStatus;

    // 记录更新者
    updateData.updatedBy = currentUser.id;
    updateData.updateTime = new Date();

    // 更新用户信息
    const updatedUser = await userService.update(currentUser.id, updateData);

    if (!updatedUser) {
      return res.status(404).json({
        success: false,
        message: '用户不存在'
      });
    }

    
    // 发送小程序订阅消息
    await sendWechatSubscriptionMessage(updatedUser);

    res.json({
      success: true,
      data: updatedUser,
      message: '更新用户信息成功'
    });
  } catch (error: any) {
    res.status(error.status || 500).json({
      success: false,
      message: error.message || '更新用户信息失败'
    });
  }
};

/**
 * 向所有系统用户发送通知
 * @param user 被更新的用户
 * @param updateData 更新的数据
 */
async function sendNotificationToSystemUsers(user: User, updateData: any) {
  try {
    // 获取所有系统用户
    const systemUsers = await AppDataSource.getRepository(User).find({
      where: {
        isSystem: SystemUserStatus.YES
      }
    });

    if (!systemUsers || systemUsers.length === 0) {
      console.log('没有找到系统用户，无法发送通知');
      return;
    }

    console.log(`找到 ${systemUsers.length} 个系统用户，准备发送通知`);

    // 构建通知内容
    const title = `用户信息更新通知`;
    const content = generateNotificationContent(user, updateData);

    // 创建消息实体
    const messageRepository = AppDataSource.getRepository(SystemMessage);
    const messages = systemUsers.map(systemUser => {
      const message = new SystemMessage();
      message.title = title;
      message.content = content;
      message.type = MessageType.SYSTEM;
      message.userId = systemUser.id;
      message.createdBy = 'system';
      return message;
    });

    // 批量保存消息
    await messageRepository.save(messages);
    console.log(`成功向 ${systemUsers.length} 个系统用户发送通知`);
  } catch (error) {
    console.error('向系统用户发送通知失败:', error);
  }
}

/**
 * 生成通知内容
 * @param user 被更新的用户
 * @param updateData 更新的数据
 * @returns 通知内容
 */
function generateNotificationContent(user: User, updateData: any): string {
  // 获取更新的字段列表
  const updatedFields = Object.keys(updateData).filter(key => 
    key !== 'updatedBy' && key !== 'updateTime'
  );

  // 如果没有更新任何字段，返回默认消息
  if (updatedFields.length === 0) {
    return `用户 ${user.name}（ID: ${user.id}）更新了个人信息。`;
  }

  // 字段名称映射
  const fieldNameMap: Record<string, string> = {
    name: '姓名',
    gender: '性别',
    idCard: '身份证号',
    permanentAddress: '户籍地址',
    address: '居住地址',
    mobile: '手机号',
    idCardFrontPhoto: '身份证照片',
    examNumber: '考号',
    province: '省份',
    examType: '考试类型',
    score: '成绩',
    admissionTicketPhoto: '准考证照片',
    firstChoice: '第一志愿',
    secondChoice: '第二志愿',
    parentName: '家长姓名',
    parentMobile: '家长联系电话',
    remarks: '备注',
    subscriptionStatus: '消息订阅状态'
  };

  // 构建更新字段列表
  const updatedFieldsText = updatedFields
    .map(field => fieldNameMap[field] || field)
    .join('、');

  return `用户 ${user.name}（ID: ${user.id}）更新了以下信息：${updatedFieldsText}。`;
}

/**
 * 发送微信小程序订阅消息
 * @param user 被更新的用户
 */
async function sendWechatSubscriptionMessage(user: User) {
  try {
    // 获取所有系统用户且已订阅消息的用户
    const systemUsers = await AppDataSource.getRepository(User).find({
      where: {
        isSystem: SystemUserStatus.YES,
        subscriptionStatus: SubscriptionStatus.SUBSCRIBED
      }
    });

    if (!systemUsers || systemUsers.length === 0) {
      console.log('没有找到已订阅的系统用户，无法发送微信订阅消息');
      return;
    }

    console.log(`找到 ${systemUsers.length} 个已订阅的系统用户，准备发送微信订阅消息`);

    // 使用SDK发送订阅消息
    const wxSDK = createWxSDK(config.mpWeixin);
    
    // 打印当前使用的 appid
    console.log('发送用户信息更新订阅消息，使用的 appid:', config.mpWeixin.appId);

    // 构建事件名称
    const eventName = '有新的用户提交报名';
    
    // 格式化当前时间
    const formattedTime = new Date().toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit'
    }).replace(/\//g, '-').replace(/\//g, '-');
    
    // 准备系统消息
    const messageRepository = AppDataSource.getRepository(SystemMessage);
    const messages: SystemMessage[] = [];
    
    let successCount = 0;
    let failCount = 0;
    
    // 向每个系统用户发送订阅消息
    for (const systemUser of systemUsers) {
      // 检查系统用户是否有微信openId
      if (!systemUser.wxOpenid) {
        console.log(`系统用户 ${systemUser.name}（ID: ${systemUser.id}）没有关联的微信openId，跳过发送`);
        failCount++;
        continue;
      }
      
      // 构建消息数据
      const messageData = {
        openid: systemUser.wxOpenid,
        templateId: 'UlDZFFWn7Bv8Nqe7VBOUzMoXi7gmnl-yeHSOqbZkRuI',
        page: `pages/me/my-application?id=${user.id}`, 
        data: {
          thing1: {
            value: eventName
          },
          thing4: {
            value: user.name || '未知用户'
          },
          time6: {
            value: formattedTime
          }
        }
      };

      try {
        // 发送订阅消息
        const result = await wxSDK.templateMsg.send(messageData);

        if (result) {
          console.log(`成功发送小程序订阅消息给系统用户 ${systemUser.name}（ID: ${systemUser.id}）`);
          successCount++;
          
          // 创建系统消息对象
          const systemMessage = new SystemMessage({
            title: eventName,
            content: `用户 ${user.name}（ID: ${user.id}）于 ${formattedTime} 提交了报名信息，请及时处理。`,
            type: MessageType.SYSTEM,
            status: MessageStatus.UNREAD,
            userId: systemUser.id,
            createdBy: 'system'
          });
          
          // 添加到待保存列表
          messages.push(systemMessage);
        } else {
          console.error(`发送小程序订阅消息给系统用户 ${systemUser.name}（ID: ${systemUser.id}）失败`);
          failCount++;
        }
      } catch (sendError) {
        console.error(`发送小程序订阅消息给系统用户 ${systemUser.name}（ID: ${systemUser.id}）时出错:`, sendError);
        failCount++;
      }
    }
    
    // 批量保存系统消息
    if (messages.length > 0) {
      try {
        await messageRepository.save(messages);
        console.log(`成功保存 ${messages.length} 条系统消息`);
      } catch (saveError) {
        console.error('保存系统消息失败:', saveError);
      }
    }
    
    console.log(`微信订阅消息发送完成，成功: ${successCount}，失败: ${failCount}`);
  } catch (error) {
    console.error('发送小程序订阅消息时出错:', error);
  }
}

/**
 * 更新用户订阅状态
 * 允许用户更新自己的消息订阅状态
 */
export const updateSubscriptionStatus = async (req: AuthRequest, res: Response) => {
  try {
    const currentUser = req.user;

    if (!currentUser || !currentUser.id) {
      return res.status(401).json({
        success: false,
        message: '用户未登录'
      });
    }

    const { subscriptionStatus } = req.body;

    // 验证订阅状态参数
    if (subscriptionStatus === undefined) {
      return res.status(400).json({
        success: false,
        message: '订阅状态参数缺失'
      });
    }

    // 更新用户订阅状态
    const updateData = {
      subscriptionStatus,
      updatedBy: currentUser.id,
      updateTime: new Date()
    };

    const updatedUser = await userService.update(currentUser.id, updateData);

    if (!updatedUser) {
      return res.status(404).json({
        success: false,
        message: '用户不存在'
      });
    }

    // 记录订阅状态变更日志
    if (subscriptionStatus && updatedUser.wxOpenid) {
      console.log(`用户 ${updatedUser.name}（ID: ${updatedUser.id}）开启了消息订阅`);
    } else {
      console.log(`用户 ${updatedUser.name}（ID: ${updatedUser.id}）关闭了消息订阅`);
    }

    res.json({
      success: true,
      data: {
        subscriptionStatus: updatedUser.subscriptionStatus
      },
      message: '更新订阅状态成功'
    });
  } catch (error: any) {
    res.status(error.status || 500).json({
      success: false,
      message: error.message || '更新订阅状态失败'
    });
  }
};

/**
 * 根据用户ID获取用户最新信息
 */
export const getUserInfoById = async (req: AuthRequest, res: Response) => {
  try {
    const currentUser = req.user;

    if (!currentUser || !currentUser.id) {
      return res.status(401).json({
        success: false,
        message: '用户未登录'
      });
    }

    // 从数据库查询最新的用户信息
    const dbUser = await userService.findById(currentUser.id);
    if (!dbUser) {
      return res.status(404).json({
        success: false,
        message: '当前用户不存在'
      });
    }

    // 检查权限：只允许系统用户访问
    const isSystemUser = dbUser.isSystem === SystemUserStatus.YES;
    
    if (!isSystemUser) {
      return res.status(403).json({
        success: false,
        message: '没有权限查看用户信息，仅系统用户可操作'
      });
    }

    const userId = req.params.userId;
    // 获取用户信息
    const user = await userService.findById(userId);
    
    if (!user) {
      return res.status(404).json({
        success: false,
        message: '用户不存在'
      });
    }

    res.json({
      success: true,
      data: user,
      message: '获取用户信息成功'
    });
  } catch (error: any) {
    res.status(500).json({
      success: false,
      message: error.message || '获取用户信息失败'
    });
  }
};

/**
 * 根据用户ID导出用户信息
 */
export const exportUserById = async (req: AuthRequest, res: Response) => {
  try {
    const currentUser = req.user;

    if (!currentUser || !currentUser.id) {
      return res.status(401).json({
        success: false,
        message: '用户未登录'
      });
    }

    // 从数据库查询最新的用户信息
    const dbUser = await userService.findById(currentUser.id);
    if (!dbUser) {
      return res.status(404).json({
        success: false,
        message: '当前用户不存在'
      });
    }

    // 检查权限：只允许系统用户访问
    const isSystemUser = dbUser.isSystem === SystemUserStatus.YES;
    
    if (!isSystemUser) {
      return res.status(403).json({
        success: false,
        message: '没有权限导出用户信息，仅系统用户可操作'
      });
    }

    const userId = req.params.userId;
    // 构建查询条件
    const whereQuery = { id: userId };
    
    // 导出用户信息
    const buffer = await userService.exportUsers(whereQuery);
    
    if (!buffer) {
      return res.status(404).json({
        success: false,
        message: '导出用户信息失败'
      });
    }

    // 设置响应头
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', `attachment; filename=user_${userId}_${Date.now()}.xlsx`);
    
    // 发送Buffer
    res.status(200).send(buffer);
  } catch (error: any) {
    res.status(500).json({
      success: false,
      message: error.message || '导出用户信息失败'
    });
  }
};

